﻿using System;
using System.Net;
using System.Collections.Generic;
using SCG.SolarVengeanceEngine.BrainInfo;

namespace SCG.SolarVengeanceEngine
{
    //UDOs
    public class UDO : SVMapObject
    {
        //constructors
        public UDO(SVGame game, string name, string imageFileName)
            : base(game)
        {
            Name = name;
            ImageFileName = imageFileName;
            Game.UDOs.Add(this);
            foreach (Player p in game.Players)
                TaggedBy[p] = false;
            AutoPickUp = true;
        }
        public UDO(SVGame game)
            : base(game)
        {
            Game.UDOs.Add(this);
            foreach (Player p in game.Players)
                TaggedBy[p] = false;
        }

        //Remove from game
        public override void Remove()
        {
            base.Remove();
            Game.UDOs.Remove(this);
            Carrier = null;
        }

        //The "name" of the UDO - should be unique
        public string Name { get; set; }

        //use name as DisplayName
        public override string DisplayName
        {
            get
            {
                return Name;
            }
        }

        //allow patrols into its space
        public override bool CanPatrolInto
        {
            get
            {
                return true;
            }
        }

        //The image that should represent the UDO
        public string ImageFileName { get; set; }

        //Desription - what appears when its clicked on the map
        public string Description { get; set; }

        //Does this UDO automatically get picked up by a StarShip?
        public bool AutoPickUp { get; set; }

        //Is it effected by blackholes?
        public bool IgnoreBlackHoles { get; set; }

        //Can it be tagged by Inkspots?
        public bool IsTaggable { get; set; }

        //The StarShip that currently holds the UDO
        public StarShip Carrier
        {
            get
            {
                return _carrier;
            }
            set
            {
                if (_carrier != null)
                    _carrier.UDOs.Remove(this);
                _carrier = value;
                if (_carrier != null)
                {
                    _carrier.UDOs.Add(this);
                    X = _carrier.X;
                    Y = _carrier.Y;
                }
            }
        }

        //Is it tagged?
        public Dictionary<Player, bool> TaggedBy
        {
            get
            {
                return _taggedBy;
            }
        }

        //Persistence
        public override string Persist()
        {
            SVTokenizer tok = new SVTokenizer(Game);
            tok.Tokenize(Name, Description, ImageFileName, AutoPickUp, Carrier, IgnoreBlackHoles, IsTaggable);
            foreach (Player p in Game.Players)
                tok.AppendToken(TaggedBy[p]);
            return base.Persist() + tok.Result;
        }
        public override SVTokenizer Parse(string s)
        {
            SVTokenizer tok = base.Parse(s);
            Name = tok.TokenString;
            Description = tok.TokenString;
            ImageFileName = tok.TokenString;
            AutoPickUp = tok.TokenBoolean;
            Carrier = tok.TokenStarShip;
            IgnoreBlackHoles = tok.TokenBoolean;
            IsTaggable = tok.TokenBoolean;
            foreach (Player p in Game.Players)
                TaggedBy[p] = tok.TokenBoolean;
            return tok;
        }

        //private members
        private StarShip _carrier = null;
        private Dictionary<Player, bool> _taggedBy = new Dictionary<Player, bool>();
        private UDOInfo _info = null;

        //Set location without disturbing other elements in game
        internal void SetLocationSafely(int x, int y)
        {
            if (Game.GetObjectAt(x, y) == this)
                Game.SetObjectAt(x, y, null);
            X = x;
            Y = y;
            if (Game.GetObjectAt(x, y) == null)
                Game.SetObjectAt(x, y, this);
        }

        //Access info object for brains
        internal UDOInfo Info
        {
            get
            {
                if (_info == null)
                    _info = new UDOInfo(this);
                return _info;
            }
        }
    }
}
